﻿using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.ComponentModel;
using Microsoft.SharePoint;
using System.DirectoryServices.AccountManagement;
using System.Security.Principal;
using WebPart = Microsoft.SharePoint.WebPartPages.WebPart;

namespace SDSChangePassword.SDSChangePassword
{
    /*
     * 
     * Strategic Data Systems
     * 10785 Yankee Street
     * Dayton, OH 45458
     * PH: 937-886-9405 
     * http://www.sds-consulting.com
     * http://sdssharepointlibrary.codeplex.com
     * 
     */

    /// <summary>
    /// Change Password Web part
    /// </summary>
    [Guid("1d78275d-15eb-48d8-ae2a-c861d9d37c51")]
    public class SDSChangePassword : WebPart
    {
        /// <summary>
        /// Textbox for old password
        /// </summary>
        private TextBox _oldpassword;
        /// <summary>
        /// Textbox for new password (first one)
        /// </summary>
        private TextBox _newpassword;
        /// <summary>
        /// Textbox for new password (second one)
        /// </summary>
        private TextBox _newpassword2;
        /// <summary>
        /// Label for messages
        /// </summary>
        private Label _labelmsg;
        /// <summary>
        /// Button for submitting
        /// </summary>
        private Button _submitButton;
        /// <summary>
        /// Show old password as text
        /// </summary>
        private Boolean _oldpwtype;
        /// <summary>
        /// Show new password as text
        /// </summary>
        private Boolean _newpwtype;
        /// <summary>
        /// Show expire password button
        /// </summary>
        private Boolean _nextlogonpw;
        /// <summary>
        /// Expire button
        /// </summary>
        private Button _expireButton;

        /// <summary>
        /// Show old password as text
        /// </summary>
        [Category("Configuration"),
        Personalizable(PersonalizationScope.Shared),
        WebBrowsable(true),
        WebDisplayName("Show old password as text?"),
        WebDescription("Show old password as text?")]
        public Boolean OldPwType
        {
            get { return _oldpwtype; }
            set { _oldpwtype = value; }
        }

        /// <summary>
        /// Show new password as text
        /// </summary>
        [Category("Configuration"),
        Personalizable(PersonalizationScope.Shared),
        WebBrowsable(true),
        WebDisplayName("Show new password as text?"),
        WebDescription("Show new password as text?")]
        public Boolean NewPwType
        {
            get { return _newpwtype; }
            set { _newpwtype = value; }
        }

        /// <summary>
        /// Show expire password button
        /// </summary>
        [Category("Configuration"),
        Personalizable(PersonalizationScope.Shared),
        WebBrowsable(true),
        WebDisplayName("Show button expire pw now? Next logon ask user for new password"),
        WebDescription("Show button expire pw now? Next logon ask user for new password")]
        public Boolean NextLogonPw
        {
            get { return _nextlogonpw; }
            set { _nextlogonpw = value; }
        }

        /// <summary>
        /// Constructor for class
        /// </summary>
        public SDSChangePassword()
        {
            this.AllowEdit = true;
            this.AllowClose = true;
        }

        /// <summary>
        /// Create the web controls used by this web part.
        /// </summary>
        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            this.Controls.Clear();

            _oldpassword = new TextBox();
            _oldpassword.ID = "OldPw";
            _oldpassword.CssClass = "ms-input";

            _newpassword = new TextBox();
            _newpassword.ID = "NewPw";
            _newpassword.CssClass = "ms-input";

            _newpassword2 = new TextBox();
            _newpassword2.ID = "NewPw2";
            _newpassword2.CssClass = "ms-input";

            _labelmsg = new Label();
            _labelmsg.ID = "Labelmsg";
            _labelmsg.CssClass = "ms-formvalidation";

            _submitButton = new Button();
            _submitButton.ID = "SubmitButton";
            _submitButton.CssClass = "ms-ButtonHeightWidth";
            _submitButton.Text = "OK";
            _submitButton.Click += new System.EventHandler(this._submitButton_Click);

            _expireButton = new Button();
            _expireButton.ID = "ExpireButton";
            _expireButton.CssClass = "ms-ButtonHeightWidth";
            _expireButton.Text = "OK";
            _expireButton.Click += new System.EventHandler(this._expireButton_Click);

            this.Controls.Add(_oldpassword);
            this.Controls.Add(_newpassword);
            this.Controls.Add(_newpassword2);

            this.Controls.Add(_submitButton);
            this.Controls.Add(_expireButton);
        }

        /// <summary>
        /// Render the web part on page
        /// </summary>
        /// <param name="writer">HTML text writer</param>
        protected override void Render(HtmlTextWriter writer)
        {
            if (OldPwType == false)
            {
                _oldpassword.TextMode = TextBoxMode.Password;
            }
            else
            {
                _oldpassword.TextMode = TextBoxMode.SingleLine;
            }
            if (NewPwType == false)
            {
                _newpassword.TextMode = TextBoxMode.Password;
                _newpassword2.TextMode = TextBoxMode.Password;
            }
            else
            {
                _newpassword.TextMode = TextBoxMode.SingleLine;
                _newpassword2.TextMode = TextBoxMode.SingleLine;
            }

            writer.WriteLine("<table>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td colspan=\"2\">");
            _labelmsg.RenderControl(writer);
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td>User: ");
            writer.WriteLine("</td>");
            writer.WriteLine("<td> " + SPContext.Current.Web.CurrentUser.LoginName.ToString());
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td class=\"ms-formlabel\">Old Password: ");
            writer.WriteLine("</td>");
            writer.WriteLine("<td class=\"ms-formlabel\" >");
            _oldpassword.RenderControl(writer);
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td class=\"ms-formlabel\">New Password: ");
            writer.WriteLine("</td>");
            writer.WriteLine("<td class=\"ms-formlabel\">");
            _newpassword.RenderControl(writer);
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td class=\"ms-formlabel\">Retype New Password: ");
            writer.WriteLine("</td>");
            writer.WriteLine("<td class=\"ms-formlabel\">");
            _newpassword2.RenderControl(writer);
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td height=\"10\" class=\"ms-formlabel\">");
            writer.WriteLine("</td>");
            writer.WriteLine("<td class=\"ms-formlabel\">");
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");
            writer.WriteLine("<tr>");
            writer.WriteLine("<td>");
            writer.WriteLine("</td>");
            writer.WriteLine("<td align=\"right\">");
            _submitButton.RenderControl(writer);
            writer.WriteLine("</td>");
            writer.WriteLine("</tr>");

            if (NextLogonPw == true)
            {
                writer.WriteLine("<tr>");
                writer.WriteLine("<td class=\"ms-formlabel\" colspan=\"2\">Others commands");
                writer.WriteLine("</td>");
                writer.WriteLine("</tr>");

                writer.WriteLine("<tr>");
                writer.WriteLine("<td>Expire password next logon?");
                writer.WriteLine("</td>");
                writer.WriteLine("<td align=\"right\">");
                _expireButton.RenderControl(writer);
                writer.WriteLine("</td>");
                writer.WriteLine("</tr>");
            }
            writer.WriteLine("</table>");
        }

        /// <summary>
        /// Submit button clicked event
        /// </summary>
        /// <param name="sender">Standard sender object</param>
        /// <param name="e">Standard EventArgs</param>
        protected void _submitButton_Click(object sender, EventArgs e)
        {
            if (String.IsNullOrEmpty(_oldpassword.Text) ||
                String.IsNullOrEmpty(_newpassword.Text) ||
                String.IsNullOrEmpty(_newpassword2.Text))
            {
                _labelmsg.Text = "One or more fields are empty.";
            }
            else
            {
                if (!_newpassword.Text.Equals(_newpassword2.Text))
                {
                    _labelmsg.Text = "New password fields are not the same, please retype passwords.";
                }
                else
                {
                    SPSecurity.RunWithElevatedPrivileges(

                                delegate()
                                {
                                    try
                                    {
                                        WindowsImpersonationContext aspContext = null;

                                        WindowsIdentity identity = WindowsIdentity.GetCurrent();
                                        aspContext = identity.Impersonate();
                                        ContextOptions o = ContextOptions.Negotiate;

                                        PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

                                        UserPrincipal u = new UserPrincipal(ctx);
                                        u = UserPrincipal.FindByIdentity(ctx, SPContext.Current.Web.CurrentUser.LoginName);

                                        try
                                        {
                                            u.ChangePassword(_oldpassword.Text, _newpassword.Text);
                                            _labelmsg.Text = "Password change successful";
                                        }
                                        catch (PasswordException ex)
                                        {
                                            _labelmsg.Text = ex.Message.ToString();

                                        }
                                    }
                                    catch (Exception ex)
                                    {

                                        _labelmsg.Text = "Wrong old password";
                                    }
                                });
                }
            }
        }

        /// <summary>
        /// Expire button clicked event
        /// </summary>
        /// <param name="sender">Standard sender object</param>
        /// <param name="e">Standard EventArgs</param>
        protected void _expireButton_Click(object sender, EventArgs e)
        {
            SPSecurity.RunWithElevatedPrivileges(
                        delegate()
                        {
                            try
                            {
                                WindowsImpersonationContext aspContext = null;

                                WindowsIdentity identity = WindowsIdentity.GetCurrent();
                                aspContext = identity.Impersonate();
                                ContextOptions o = ContextOptions.Negotiate;

                                PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

                                UserPrincipal u = new UserPrincipal(ctx);
                                u = UserPrincipal.FindByIdentity(ctx, SPContext.Current.Web.CurrentUser.LoginName);

                                u.ExpirePasswordNow();

                                _labelmsg.Text = "Command successful";
                            }
                            catch (Exception ex)
                            {
                                _labelmsg.Text = ex.Message.ToString();
                            }
                        });
        }
    }

}
